//
// Created by dqchen on 2022/12/12.
//

#include "symbol.h"
#include "iostream"


Func::Func() {

}

Func::Func(Tag t, string n, vector<Var*>& ps) {
    rtype = t;
    name = n;
    params = ps;
    esp = 0;
    max_esp = 0;
    sys_func = false;
    //为参数设置偏移量
    int offset = 4;
    for (int i = 0; i < params.size() ; ++i) {
        offset+=4;
        params[i]->setOffset(offset);
    }
}

Func::Func(Tag t, string n, bool sys) {
    rtype = t;
    name = n;
    sys_func = sys;
    esp = 0;
    max_esp = 0;

}

Func::~Func() {

}

string Func::getName() {
    return name;
}

Tag Func::getType() {
    return rtype;
}

void Func::addOrder(Order *order) {
    orders.push_back(order);
}

void Func::setName(string n) {
    name = n;
}

void Func::setRet(Order *r) {
    retLab = r;
}

vector<Order *> Func::getOrders() {
    return orders;
}

void Func::allocEsp(Var *var) {
    if("" == name){
        return;
    }
    if (var->getName().rfind("^", 0) == 0) {
        return;
    }
    int size = var->getSize();
    //小于4取4字节，大于4取整数倍
    if(size != 4){
        size = (size / 4 +1)*4;
    }
    scope.back() += size;
    esp+=size;
    var->setOffset(-esp);
    //最大esp
    max_esp += size;
}

Order *Func::getRet() {
    return retLab;
}

void Func::incScope() {
    scope.push_back(0);
}

void Func::decScope() {
    scope.pop_back();
}

int Func::getMaxEsp() {
    return max_esp;
}

bool Func::isSys() {
    return sys_func;
}


void Var::init(Tag t) {
    scope.push_back(-1);
    size = 0;
    data = nullptr;
    if(t == INT){
        size = 4;
    } else if (t == CHAR) {
        size = 1;
    } else if(t == BOL){
        size = 4;
    }
}


string Var::getName() {
    return name;
}

void Var::setName(string n) {
    name = n;
}

Tag Var::getType() {
    return type;
}

void Var::setData(Var *v){
    data = v;
}

Var *Var::getData() {
    return data;
}

Var::Var() {
    cout << "delete var" << endl;
}

Var::Var(Tag t, string n) {
    type = t;
    name = n;
}

Var::Var(Token *t) {
    Tag tag = t->tag;
    type = tag;
    if (tag == NUM) {
        name = "^num";
        num_val = ((Num *) t)->value;
    } else if (tag == CHAR) {
        name = "^ch";
        ch_val = ((Char *) t)->ch;
    } else if (tag == STR) {
        name = "^str";
        str_val = ((Str *) t)->str;
    }else if (tag == BOL) {
        name = "^bol";
        num_val = ((Bol *) t)->bol;
    } else if(tag == STRUCT){
        name = "^struct";
        struct_type = ((Struct *) t)->type;
    }
    init(type);
}

Var::Var(Tag t, string n,  vector<int>& s) {
    init(t);
    name = n;
    type = t;
    scope = s;
}

Var::Var(string n, Var *v, Tag t, vector<int>& s, bool ptr) {
    init(t);
    data = v;
    name = n;
    str_val = "";
    scope = s;
    type = t;
    pointer = ptr;
}

Var::~Var() {


}

string Var::getStrVal() {
    return str_val;
}

int Var::getNumVal() {
    return num_val;
}

char Var::getCharVal() {
    return ch_val;
}
//输出中间代码
void Var::printMid(FILE *midf) {
    if(type == NUM){
        fputs(to_string(num_val).c_str(), midf);
    } else if(type == CHAR){
        fputs(to_string(ch_val).c_str(), midf);
    }else if(type == STR){
        fputs(str_val.empty() ? name.c_str() : str_val.c_str() , midf);
    }else{
        fputs(name.c_str(), midf);
    }
}

int Var::getSize() {
    return size;
}

void Var::setOffset(int val) {
    offset = val;
}

int Var::getOffset() {
    return offset;
}

void Var::setPtrVal(Var *v) {
    ptr_val = v;
}

bool Var::isTemp() {
    return name.rfind("temp") == 0;
}

void Var::addStructVar(Var *v) {
    struct_var.push_back(v);
    Tag t = v->type;
    if(t == INT){
        size += 4;
    } else if (t == CHAR) {
        size += 1;
    } else if(t == BOL){
        size += 4;
    }

}

Var::Var(Tag t, string n, bool p) {
    type = t;
    name = n;
    pointer = p;
    init(t);

}

Var *Var::getStructVar(string name) {
    for(int i = 0; i < struct_var.size(); i++){
        Var *v = struct_var[i];
        if(v->name == name){
            return v;
        }
    }
    return nullptr;
}

string Var::getStructType() {
    return struct_type;
}

vector<Var *> Var::getStructVar() {
    return struct_var;
}

void Var::setStructVar(vector<Var*> v) {
    struct_var = v;
}







